﻿using System;
using System.Xml;
using System.IO;
using System.Collections.Generic;
using LoveMusic.Models;

namespace LoveMusic.Helpers
{
    public class EchonestAPI
    {
        public static EchoArtistBin SearchRequest(string artistName)
        {
            try
            {
                artistName = artistName.Replace(" ", "+");
                string url = "http://developer.echonest.com/api/search_artists?api_key=GZWEIGV8SGDQMITRF&query=" + artistName + "&version=3";
                string xml = WebHelper.GetResponseStandard(url);

                return GetData(xml,artistName);
            }
            catch (Exception ex)
            {
                TraceLog.TimeWrite(ex, "AllMusicApi exception artistName=" + artistName);
                return null;
            }
        }

        private static EchoArtistBin GetData(string xml,string artistName)
        {
            XmlDocument xmlDoc = GetXmlDocument(xml);
            List<EchoArtistBin> echoList = new List<EchoArtistBin>();
            EchoArtistBin artistBin = null;
            EchoNestStatus echoArtistIDStatus = GetStatus(xmlDoc);

            #region Get Artists

            if (echoArtistIDStatus == EchoNestStatus.Success)
            {
                XmlNodeList artists = xmlDoc.GetElementsByTagName("artist");
                if (artists.Count != 0)
                {
                    foreach (XmlElement element in artists)
                    {
                        EchoArtistBin echoArtistBin = new EchoArtistBin();
                        echoArtistBin.EchoID = element.GetElementsByTagName("id")[0].InnerXml;
                        echoArtistBin.Name = element.GetElementsByTagName("name")[0].InnerXml;
                        echoList.Add(echoArtistBin);
                    }
                }
                else
                    echoArtistIDStatus = EchoNestStatus.Not_found;
            }

            #endregion

            #region Get Artist Data

            if (echoArtistIDStatus == EchoNestStatus.Success)
            {
                artistBin = echoList[0];
                artistBin.Name = artistName;
                string url = "http://developer.echonest.com/api/get_profile?api_key=GZWEIGV8SGDQMITRF&id=" + artistBin.EchoID + "&version=3"
                    + "&bucket=audio"
                    + "&bucket=biographies"
                    + "&bucket=blogs"
                    + "&bucket=familiarity"
                    + "&bucket=hotttnesss"
                    + "&bucket=images"
                    + "&bucket=news"
                    + "&bucket=reviews"
                    + "&bucket=urls"
                    + "&bucket=video"
                    + "&bucket=reviews";


                string strXml = WebHelper.GetResponseStandard(url);
                XmlDocument xmlDocz = GetXmlDocument(strXml);
                EchoNestStatus statusGetData = GetStatus(xmlDocz);

                if (statusGetData == EchoNestStatus.Success)
                {
                    #region Biography

                    try
                    {
                        XmlNodeList nodeListBiographies = xmlDocz.GetElementsByTagName("biographies")[0].ChildNodes;
                        if (nodeListBiographies.Count != 0)
                        {
                            artistBin.Biographies = new List<Bio>();
                            foreach (XmlElement element in nodeListBiographies)
                            {
                                Bio bio = new Bio();
                                bio.Text = element.GetElementsByTagName("text")[0].InnerXml;
                                bio.SourceUrl = element.GetElementsByTagName("url")[0].InnerXml;
                                try
                                {
                                    bio.SiteName = element.GetElementsByTagName("site")[0].InnerXml;
                                }
                                catch (Exception e)
                                {
                                }
                                artistBin.Biographies.Add(bio);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        TraceLog.TimeWrite(ex, "Biographii od ekonest");
                        echoArtistIDStatus = EchoNestStatus.Unknown_error;
                    }

                    #endregion

                    #region Blogs

                    try
                    {
                        XmlNodeList nodeListBlogs = xmlDocz.GetElementsByTagName("blogs")[0].ChildNodes;
                        if (nodeListBlogs.Count != 0)
                        {
                            artistBin.Blogs = new List<Blog>();
                            foreach (XmlElement element in nodeListBlogs)
                            {
                                Blog blog = new Blog();
                                blog.Name = element.GetElementsByTagName("name")[0].InnerXml;
                                blog.Url = element.GetElementsByTagName("url")[0].InnerXml;
                                blog.Summary = element.GetElementsByTagName("summary")[0].InnerXml;

                                artistBin.Blogs.Add(blog);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        TraceLog.TimeWrite(ex, "Biographii od ekonest");
                        echoArtistIDStatus = EchoNestStatus.Unknown_error;
                    }

                    #endregion

                    #region Reviews

                    try
                    {
                        XmlNodeList nodeListReviews = xmlDocz.GetElementsByTagName("reviews")[0].ChildNodes;
                        if (nodeListReviews.Count != 0)
                        {
                            artistBin.Reviews = new List<Review>();
                            foreach (XmlElement element in nodeListReviews)
                            {
                                Review review = new Review();
                                review.Name = element.GetElementsByTagName("name")[0].InnerXml;
                                try
                                {
                                    review.ImageUrl = element.GetElementsByTagName("image_url")[0].InnerXml;
                                    review.ReleaseName = element.GetElementsByTagName("release")[0].InnerXml;
                                }
                                catch (Exception e)
                                {
                                }
                                review.Url = element.GetElementsByTagName("url")[0].InnerXml;
                                review.Summary = element.GetElementsByTagName("summary")[0].InnerXml;

                                artistBin.Reviews.Add(review);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        TraceLog.TimeWrite(ex, "Biographii od ekonest");
                        echoArtistIDStatus = EchoNestStatus.Unknown_error;
                    }

                    #endregion

                    #region Images
                    try
                    {
                        artistBin.Images = new List<IMAGE>();
                        XmlNodeList nodeListImages = xmlDocz.GetElementsByTagName("images")[0].ChildNodes;
                        if (nodeListImages.Count != 0)
                        {
                            
                            int counter = 0;
                            foreach (XmlElement element in nodeListImages)
                            {
                                IMAGE image = new IMAGE();
                                image.URL = element.InnerXml;
                                if (counter==0)
                                    image.TYPE = "primary";
                                else
                                    image.TYPE = "secondary";
                                counter++;
                                artistBin.Images.Add(image);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                    }

                    #endregion 

                    try
                    {
                        artistBin.familiarity = Double.Parse(xmlDocz.GetElementsByTagName("familiarity")[0].InnerXml);
                        artistBin.hotttnesss = Double.Parse(xmlDocz.GetElementsByTagName("hotttnesss")[0].InnerXml);
                    }
                    catch (Exception ex)
                    {
                        TraceLog.TimeWrite(ex, "Hotness od ekonest");
                        echoArtistIDStatus = EchoNestStatus.Unknown_error;
                    }

                }
            }

            #endregion

            return artistBin;
        }

        #region Utility

        private static XmlDocument GetXmlDocument(string xml)
        {
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(new StringReader(xml));
            return xmlDoc;
        }

        private static EchoNestStatus GetStatus(XmlDocument xmlDoc)
        {
            EchoNestStatus echoStatus = EchoNestStatus.None;
            foreach (XmlElement element in xmlDoc.GetElementsByTagName("status"))
            {
                string code = element.GetElementsByTagName("code")[0].InnerXml;
                echoStatus = (EchoNestStatus)Enum.Parse(typeof(EchoNestStatus), code);
                break;
            }
            return echoStatus;
        }

        #endregion

    }
}